package com.jeasonzhao.commons.inplacecache;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Timer;
import java.util.TimerTask;

/**
 * Timed cache. Not limited by size, objects are removed only when they are expired.
 * Prune is not invoked explicitly by standard {@link Cache} methods, however,
 * it is possible to schedule prunes on fined-rate delays.
 */
public class TimedCache<K,V> extends AbstractCacheMap<K,V>
{

    public TimedCache(long timeout)
    {
        super(0,timeout,new HashMap<K,CacheObject<K,V>>());
    }

    @Override
    public int prune()
    {
        int count = 0;
        Iterator<CacheObject<K,V>> values = null == this.getCacheMap() ? null : this.getCacheMap().values().iterator();
        while(null!=values && values.hasNext())
        {
            CacheObject<K,V> co = values.next();
            if(co.isExpired() == true)
            {
                values.remove();
                count++;
            }
        }
        return count;
    }

    private Timer pruneTimer;

    public void schedulePrune(long delay)
    {
        if(pruneTimer != null)
        {
            pruneTimer.cancel();
        }
        pruneTimer = new Timer();
        pruneTimer.schedule(
            new TimerTask()
        {
            @Override
            public void run()
            {
                prune();
            }
        },delay,delay
            );
    }

    public void cancelPruneSchedule()
    {
        if(pruneTimer != null)
        {
            pruneTimer.cancel();
            pruneTimer = null;
        }
    }

}
